package com.jyxd.web.service.qualitycontrol;

import cn.hutool.core.collection.CollectionUtil;
import com.jyxd.web.dao.basic.DrainageTubeRecordDao;
import com.jyxd.web.dao.basic.VitalSignMergeDao;
import com.jyxd.web.dao.czform.CRRTNurseDao;
import com.jyxd.web.dao.log.IcuLogDao;
import com.jyxd.web.dao.patient.PatientControlDao;
import com.jyxd.web.dao.patient.PatientDao;
import com.jyxd.web.dao.patient.PatientScoreDao;
import com.jyxd.web.data.basic.DrainageTubeRecord;
import com.jyxd.web.data.dto.ApacheStatisticsReturnDTO;
import com.jyxd.web.data.dto.HttpResult;
import com.jyxd.web.data.dto.InOutDepartmentDTO;
import com.jyxd.web.data.log.IcuLog;
import com.jyxd.web.data.patient.Patient;
import com.jyxd.web.data.patient.PatientScore;
import com.jyxd.web.error.JyxdException;
import com.jyxd.web.util.ExcelData;
import com.jyxd.web.util.ExportExcelUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import static com.jyxd.web.util.DateUtil.getLaterHoursDate;
import static com.jyxd.web.util.DateUtil.yyyyMMddHHmmssSdfToString;
import static com.jyxd.web.util.ExecuteUtil.errorIfEmpty;
import static com.jyxd.web.util.ExecuteUtil.isEmpty;
import static com.jyxd.web.util.ObjectUtil.castList;
import static com.jyxd.web.util.SliceUpDateUtil.sliceUpDateRange;

/**
 * 质控管理
 */
@Service("qualityControlService")
@Transactional
public class QualitycontrolService {

    @Autowired
    private PatientDao patientDao;
    @Autowired
    private PatientScoreDao patientScoreDao;
    @Autowired
    private DrainageTubeRecordDao drainageTubeRecordDao;

    @Autowired
    private PatientControlDao patientControlDao;

    @Autowired
    private VitalSignMergeDao vitalSignMergeDao;

    @Autowired
    private IcuLogDao icuLogDao;
    @Autowired
    private CRRTNurseDao crrtNurseDao;


    private final String QUALITYCONTROL_TYPE_ICU_PLAN = "icu_plan";  // 质控--icu非计划入科
    private final String QUALITYCONTROL_TYPE_PATIENT_DIE = "patient_die"; // 质控--患者死亡
    private final String QUALITYCONTROL_TYPE_ICU_INTUBATION = "icu_intubation"; // 质控--icu气管插拔管
    private final String QUALITYCONTROL_TYPE_3hBundle = "icu_3hBundle";  // 质控--icu3hBunble
    private final String QUALITYCONTROL_TYPE_6hBundle = "icu_6hBundle";  // 质控--6hBunble
    private final String QUALITYCONTROL_TYPE_VAP = "icu_VAP";  // 质控--VAP
    private final String QUALITYCONTROL_TYPE_DVT = "icu_DVT";  // 质控--DVT
    private final String QUALITYCONTROL_TYPE_PATIENT_GIVE = "QUALITYCONTROL_TYPE_PATIENT_GIVE";  // 收治率
    private final String QUALITYCONTROL_TYPE_BEDTODAY = "QUALITYCONTROL_TYPE_BEDTODAY";  // 床日率
    private final String QUALITYCONTROL_TYPE_PIPELINE48H = "QUALITYCONTROL_TYPE_PIPELINE48H";  // 48h插拔管
    private final String QUALITYCONTROL_TYPE_BACILLOSOS = "QUALITYCONTROL_TYPE_BACILLOSOS";  // 送检率
    private final String QUALITYCONTROL_TYPE_CRBSI = "QUALITYCONTROL_TYPE_CRBSI";  // CRBSI
    private final String QUALITYCONTROL_TYPE_CAUTI = "QUALITYCONTROL_TYPE_CAUTI";  // CAUTI
    private final String QUALITYCONTROL_TYPE_CRRT = "QUALITYCONTROL_TYPE_CRRT"; // crrt

    private static final String PARAMMONTH = "月";  //参数类型：月
    private static final String PARAMQUARTER = "季";  //参数类型：季
    private static final String PARAMYEAR = "年";  //参数类型：年

    private Map<String, Object> listMap = new HashMap<String, Object>();
    private List<String> dateTimeList = new ArrayList<String>();
    private List<Integer> moleculeNumList = new ArrayList<Integer>();
    private List<Integer> denominatorList = new ArrayList<Integer>();
    private List<String> rateList = new ArrayList<String>();

    // 初始化公共集合
    private void initializeList() {
        listMap = new HashMap<>();
        dateTimeList = new ArrayList<>();
        moleculeNumList = new ArrayList<>();
        denominatorList = new ArrayList<>();
        rateList = new ArrayList<>();
    }

    /**
     * 获取非计划进入icu质控统计数据 （折线展示统计）
     *
     * @param map
     * @return
     */
    public HttpResult getICUPlanBrokenList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_ICU_PLAN);
    }

    /**
     * 获取非计划进入icu质控统计数据 （列表展示统计）
     *
     * @param map
     * @return
     */
    public HttpResult getICUPlanNumList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_ICU_PLAN), "数据请求成功");
    }

    /**
     * 导出非计划icu （导出excel）
     */
    public HttpResult downloadIcuPlanTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_ICU_PLAN, "非计划转入ICU信息统计表", "非计划转入患者",
                "转入患者", "非计划转入占比（%）");
    }


    /**
     * 获取病死质控统计数据 （折线展示统计）
     *
     * @param map
     * @return
     */
    public HttpResult getPatientDieList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_PATIENT_DIE);
    }

    /**
     * 获取病死质控统计数据 （列表展示统计）
     *
     * @param map
     * @return
     */
    public HttpResult getPatientDieNumList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_PATIENT_DIE), "数据请求成功");
    }

    /**
     * 导出病死质控 （导出excel）
     */
    public HttpResult downloadPatientDieTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_PATIENT_DIE, "ICU死亡患者数信息统计表", "ICU死亡患者数",
                "转入患者", " ICU实际病死率（%）");
    }


    /**
     * 获取非计划icu气管插拔管质控统计数据 （折线展示统计）
     *
     * @param map
     * @return
     */
    public HttpResult getIcuIntubationList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_ICU_INTUBATION);
    }

    /**
     * 获取非计划icu气管插拔管质控统计数据 （列表展示统计）
     *
     * @param map
     * @return
     */
    public HttpResult getIcuIntubationNumList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_ICU_INTUBATION), "数据请求成功");
    }

    /**
     * 导出非计划icu气管插拔管 （导出excel）
     */
    public HttpResult downloadIcuIntubationTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_ICU_INTUBATION, "ICU非计划气管插管拔管信息统计表", "非计划气管插管拔管例数",
                "气管插管拔管总数", "ICU非计划气管插管拔管率（%）");
    }

    /**
     * 获取导出列表
     *
     * @param map
     * @param response
     * @return
     */
    private HttpResult getDownloadTotal(Map<String, Object> map, HttpServletResponse response, String qualitycontrolType,
                                        String titleText, String oneTitleText, String twoTitleText, String threeTitleText) {
        List<InOutDepartmentDTO> downloadList = getInOutDepartmentList(map, qualitycontrolType);
        if (CollectionUtil.isEmpty(downloadList)) {
            return new HttpResult(200, "数据查询为空，导出失败");
        }
        try {
            ExportExcelUtil.exportExcel(response, titleText + System.currentTimeMillis() + ".xls",
                    setExcelIcuPlanData(titleText, oneTitleText,
                            twoTitleText, threeTitleText, downloadList));
            return new HttpResult(200, "数据导出成功");
        } catch (Exception e) {
            return new HttpResult(500, "内部服务器错误，导出失败");
        }
    }


    /**
     * 表格数据导出
     *
     * @param list
     * @return
     */
    private ExcelData setExcelIcuPlanData(String titleText, String oneTitleText, String twoTitleText, String threeTitleText, List<InOutDepartmentDTO> list) {
        ExcelData data = new ExcelData();
        data.setName(titleText);
        List<String> titles = new ArrayList();
        titles.add("日期");
        titles.add(oneTitleText);
        titles.add(twoTitleText);
        titles.add(threeTitleText);
        data.setTitles(titles);
        List<List<Object>> rows = new ArrayList();
        list.forEach(inOutDepartmentDTO -> {
            List<Object> row1 = new ArrayList();
            row1.add(inOutDepartmentDTO.getDataTime());
            row1.add(inOutDepartmentDTO.getMolecule());
            row1.add(inOutDepartmentDTO.getDenominator());
            row1.add(inOutDepartmentDTO.getRatio());
            rows.add(row1);
        });
        data.setRows(rows);
        return data;
    }

    /**
     * 获取质控统计数据列表
     *
     * @param map
     * @return
     */
    public HttpResult getNewQualitycontrolList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
       String type = (String) map.get("type");
        Map<String, Object> parameterMap = new HashMap<>();
        if (map.containsKey("start") && map.containsKey("size")) {
            parameterMap.put("start", ((int)map.get("start")-1)*(int)map.get("size"));
            parameterMap.put("size", map.get("size"));
        }
        if (StringUtils.equals(type, PARAMMONTH))
            parameterMap.put("monthTime", map.get("year") + "-" + map.get("month"));
        if (StringUtils.equals(type, PARAMYEAR))
            parameterMap.put("yearTime", map.get("year"));
        List<Map> crrtQualityMap = crrtNurseDao.queryCrrtQuality(parameterMap);
        Integer totalCount = crrtNurseDao.queryCrrtQualityNum(parameterMap);
        return new HttpResult(200, crrtQualityMap, totalCount, "数据请求成功");
    }

    public HttpResult getCrrtExcel(Map<String, Object> map, HttpServletResponse response) {
        try {
            ExportExcelUtil.exportExcel(response, "crrt表单填写数据导出" + System.currentTimeMillis() + ".xls",
                    setCrrtExcelIcuPlanData("crrt表单填写数据导出", map));
            return new HttpResult(200, "数据导出成功");
        } catch (Exception e) {
            e.printStackTrace();
            return new HttpResult(500, "内部服务器错误，导出失败");
        }
    }

    /**
     * 表格数据导出
     *
     * @param
     * @return
     */
    private ExcelData setCrrtExcelIcuPlanData(String titleText, Map<String, Object> map) {
        ExcelData data = new ExcelData();
        data.setName(titleText);
        List<String> titles = new ArrayList();
        HttpResult resultData = getNewQualitycontrolList(map);
        titles.add("姓名");
        titles.add("住院号");
        data.setTitles(titles);
        List<List<Object>> rows = new ArrayList();
        List<Object> rowFirst = new ArrayList();
        rowFirst.add("总数");
        rowFirst.add(String.valueOf(resultData.getTotalCount()));
        rows.add(rowFirst);
        if (isEmpty(resultData.getData())) {
            data.setRows(rows);
            return data;
        }
        List<Map> crrtQualityMap = castList(resultData.getData(), Map.class);
        crrtQualityMap.forEach(mapData -> {
            List<Object> row1 = new ArrayList();
            row1.add(mapData.get("name"));
            row1.add(mapData.get("app_id"));
            rows.add(row1);
        });
        data.setRows(rows);
        return data;
    }

    /**
     * 获取列表数据
     *
     * @param map
     * @return
     */
    private List<InOutDepartmentDTO> getInOutDepartmentList(Map<String, Object> map, String qualitycontrolType) {
        LinkedList<InOutDepartmentDTO> list = new LinkedList<>();
        Map<String, Integer> numMap = new HashMap<>();
        if (map.get("type").toString().equals("按天")) {
            numMap = addList(map, list, "day", qualitycontrolType);
        } else if (map.get("type").toString().equals("按月")) {
            numMap = addList(map, list, "month", qualitycontrolType);
        }
        Integer moleculeTotalCount = numMap.get("moleculeTotalCount");
        Integer denominatorTotalCount = numMap.get("denominatorTotalCount");
        InOutDepartmentDTO sumDto = new InOutDepartmentDTO();
        sumDto.setDataTime("总计");
        sumDto.setMolecule(moleculeTotalCount + "");
        sumDto.setDenominator(denominatorTotalCount + "");
        sumDto.setRatio(calculateRate(moleculeTotalCount, denominatorTotalCount, qualitycontrolType));
        list.addFirst(sumDto);
        return list;
    }

    /**
     * 获取质控统计数据列表
     *
     * @param map
     * @return
     */
    public HttpResult getQualitycontrolList(Map<String, Object> map, String qualitycontrolType) {
        errorIfEmpty(map, "查询参数数据不能为空");
        // 初始化返回数据集合
        initializeList();
        if (map.get("type").toString().equals("按天")) {
            String startTime = map.get("startTime").toString();
            String endTime = map.get("endTime").toString();
            dateTimeList = sliceUpDateRange(startTime, endTime, 3);
            for (String dataTime : dateTimeList) {
                int molecule = getMolecule(qualitycontrolType, startTime, dataTime, "day");
                int denominator = getDenominator(qualitycontrolType, startTime, dataTime, "day");
                moleculeNumList.add(molecule);
                denominatorList.add(denominator);
                rateList.add(calculateRate(molecule, denominator, qualitycontrolType));
            }
        } else if (map.get("type").toString().equals("按月")) {
            String year = (String) map.get("year");
            dateTimeList = sliceUpDateRange(year + "-01", year + "-12", 2);
            for (String dataTime : dateTimeList) {
                int molecule = getMolecule(qualitycontrolType, year, dataTime, "month");
                int denominator = getDenominator(qualitycontrolType, year, dataTime, "month");
                moleculeNumList.add(molecule);
                denominatorList.add(denominator);
                rateList.add(calculateRate(molecule, denominator, qualitycontrolType));
            }
        }
        listMap.put("datetimeList", dateTimeList);
        listMap.put("fourAndEightNumList", moleculeNumList);
        listMap.put("transferPatientNumList", denominatorList);
        listMap.put("fourAndEightRateNumList", rateList);
        return new HttpResult(200, listMap, "数据请求成功");
    }

    /**
     * 给list中追加数据
     *
     * @param map
     * @param list
     * @param dateType
     */
    private Map addList(Map<String, Object> map,
                        LinkedList<InOutDepartmentDTO> list, String dateType, String qualitycontrolType) {
        List<String> datetimeList = new ArrayList<>();
        Integer moleculeTotalCount = 0;
        Integer denominatorTotalCount = 0;
        String startTime = "0";
        if (StringUtils.equals(dateType, "day")) {
            startTime = map.get("startTime").toString();
            String endTime = map.get("endTime").toString();
            datetimeList = sliceUpDateRange(startTime, endTime, 3);
        } else if (StringUtils.equals(dateType, "month")) {
            startTime = (String) map.get("year");
            datetimeList = sliceUpDateRange(startTime + "-01", startTime + "-12", 2);
        }
        for (String dataTime : datetimeList) {
            InOutDepartmentDTO dto = new InOutDepartmentDTO();
            dto.setDataTime(dataTime);
            //分子
            int molecule = getMolecule(qualitycontrolType, startTime, dataTime, dateType);
            //分母
            int denominator = getDenominator(qualitycontrolType, startTime, dataTime, dateType);
            String ratio = calculateRate(molecule, denominator, qualitycontrolType);
            moleculeTotalCount += molecule;
            denominatorTotalCount += denominator;
            dto.setMolecule(molecule + "");
            dto.setDenominator(denominator + "");
            dto.setRatio(ratio);
            list.add(dto);
        }
        Map<String, Integer> numMap = new HashMap<>();
        numMap.put("moleculeTotalCount", moleculeTotalCount);
        numMap.put("denominatorTotalCount", denominatorTotalCount);
        return numMap;
    }

    /**
     * 获取分子数据
     */
    private int getMolecule(String qualitycontrolType, String startTime, String dataTime, String dateType) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("dataTime", dataTime);
        paramMap.put("type", dateType);
        paramMap.put("startTime", startTime);
        switch (qualitycontrolType) {
            case QUALITYCONTROL_TYPE_ICU_PLAN:
                // 查询非计划转入患者数
                paramMap.put("unplanned", "2");
                return patientDao.getPlanPatientNum(paramMap);
            case QUALITYCONTROL_TYPE_PATIENT_DIE:
                // 查询时间段内死亡患者数
                paramMap.put("exitType", "死亡");
                return patientDao.getPlanPatientNum(paramMap);
            case QUALITYCONTROL_TYPE_ICU_INTUBATION:
                // 查询非计划插拔管记录
                paramMap.put("planFlag", 2);
                return drainageTubeRecordDao.getIntubationRecordNum(paramMap);
            case QUALITYCONTROL_TYPE_3hBundle:
                // 查询3h
                paramMap.put("planFlag", 1);
                return patientControlDao.get3hBundleRecordNum(paramMap);
            case QUALITYCONTROL_TYPE_6hBundle:
                // 查询6h
                paramMap.put("planFlag", 1);
                return patientControlDao.get6hBundleRecordNum(paramMap);
            case QUALITYCONTROL_TYPE_VAP:
                // 查询vap
                paramMap.put("planFlag", 1);
                return patientControlDao.getVapRecordNum(paramMap);
            case QUALITYCONTROL_TYPE_DVT:
                // 查询dvt
                paramMap.put("planFlag", 1);
                return patientControlDao.getDvtRecordNum(paramMap);
            case QUALITYCONTROL_TYPE_PATIENT_GIVE:
                // 收治率
                return patientDao.getNumByStartAndEndMolecule(paramMap);
            case QUALITYCONTROL_TYPE_BEDTODAY:
                // 床日率
                return patientDao.getNumByRateOfBedMolecule(paramMap);
            case QUALITYCONTROL_TYPE_PIPELINE48H:
                // 48小时再插拔
                return getDrainageTubeRecordMolecule(paramMap);
            case QUALITYCONTROL_TYPE_BACILLOSOS:
                // 送检率
                paramMap.put("planFlag", 1);
                return patientControlDao.getBacillosisNum(paramMap);
            case QUALITYCONTROL_TYPE_CRBSI:
                // CRBSI
                paramMap.put("planFlag", 1);
                return patientControlDao.getCrbsiMoleculeNum(paramMap);
            case QUALITYCONTROL_TYPE_CAUTI:
                // CAUTI
                paramMap.put("planFlag", 1);
                return patientControlDao.getCautiMoleculeNum(paramMap);
            default:
                throw new JyxdException("传入查询质控类型错误");
        }
    }

    /**
     * 获取48小时再插拔管数据
     *
     * @param map
     * @return
     */
    private int getDrainageTubeRecordMolecule(Map<String, Object> map) {
        map.put("planFlag", "1");
        List<DrainageTubeRecord> recordList = drainageTubeRecordDao.getIntubationRecord(map);
        if (CollectionUtil.isEmpty(recordList))
            return 0;
        AtomicInteger fourAndEightDrainageTubeRecordSum = new AtomicInteger();
        recordList.forEach(drainageTubeRecord -> {
            if (Objects.isNull(drainageTubeRecord.getTubeDrawingTime()))
                return;
            Date laterHoursDate = getLaterHoursDate(drainageTubeRecord.getTubeDrawingTime(), 48L);
            Map<String, Object> findMap = new HashMap<>();
            findMap.put("intubationStartTime", yyyyMMddHHmmssSdfToString(drainageTubeRecord.getTubeDrawingTime()));
            findMap.put("intubationEndTime", yyyyMMddHHmmssSdfToString(laterHoursDate));
            findMap.put("patientId", drainageTubeRecord.getPatientId());
            if (drainageTubeRecordDao.getIntubationRecordNum(findMap) > 0)
                fourAndEightDrainageTubeRecordSum.addAndGet(1);
        });
        return fourAndEightDrainageTubeRecordSum.get();
    }

    /**
     * 获取分母数据
     */
    private int getDenominator(String qualitycontrolType, String startTime, String dataTime, String dateType) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("dataTime", dataTime);
        paramMap.put("type", dateType);
        paramMap.put("startTime", startTime);
        switch (qualitycontrolType) {
            case QUALITYCONTROL_TYPE_ICU_PLAN:
            case QUALITYCONTROL_TYPE_PATIENT_DIE:
                // 查询时间段内转入患者数
                return patientDao.getPlanPatientNum(paramMap);
            case QUALITYCONTROL_TYPE_ICU_INTUBATION:
                // 查询时间段内所有插拔管记录
            case QUALITYCONTROL_TYPE_PIPELINE48H:
                // 48小时再插拔
                return drainageTubeRecordDao.getIntubationRecordNum(paramMap);
            case QUALITYCONTROL_TYPE_3hBundle:
                // 查询3h
//                return patientControlDao.get3hBundleRecordNum(paramMap);
                paramMap.put("planFlag", 1);
                return patientControlDao.getBundleRecordDenominatorNum(paramMap);
            case QUALITYCONTROL_TYPE_6hBundle:
                // 查询6h
//                return patientControlDao.get6hBundleRecordDenominatorNum(paramMap);
                paramMap.put("planFlag", 1);
                return patientControlDao.getBundleRecordDenominatorNum(paramMap);
            case QUALITYCONTROL_TYPE_VAP:
                // 查询vap分母（同期ICU患者有创机械通气总天数）
//                return getIcuVapDenominator(paramMap);
                paramMap.put("planFlag", "机械通气");
                return getIcuVapDenominator1(paramMap);
            case QUALITYCONTROL_TYPE_DVT:
                // 查询dvt
                return patientControlDao.getDvtRecordNum(paramMap);
            case QUALITYCONTROL_TYPE_PATIENT_GIVE:
                // 收治率
                paramMap.put("planFlag", 1);
                return patientDao.getNumByStartAndEndDenominator(paramMap);
            case QUALITYCONTROL_TYPE_BEDTODAY:
                // 床日率
                paramMap.put("planFlag", 1);
                return patientDao.getNumByRateOfBedDenominator(paramMap);
            case QUALITYCONTROL_TYPE_BACILLOSOS:
                // 送检率
                paramMap.put("planFlag", 1);
                return patientControlDao.getInspectionRateDenominator(paramMap);
            case QUALITYCONTROL_TYPE_CRBSI:
                // CRBSI
                return getCrbsiDenominator(paramMap);

            case QUALITYCONTROL_TYPE_CAUTI:
                // CAUTI
                return getCautiDenominator(paramMap);

            default:
                throw new JyxdException("传入查询质控类型错误");
        }
    }

    private int getCautiDenominator(Map<String, Object> paramMap) {
        paramMap.put("planFlag", "尿管");
        List<DrainageTubeRecord> drainageTubeRecords = drainageTubeRecordDao.queryAllList(paramMap);
        //获取当前时间
        long times = getTime();
        int num1 = 0;
        for (int i = 0; i < drainageTubeRecords.size(); i++) {
            DrainageTubeRecord drainageTubeRecord = drainageTubeRecords.get(i);
            //获取插管时间
            long time1 = drainageTubeRecord.getIntubationTime().getTime();
            if (drainageTubeRecord.getTubeDrawingTime() != null) {
                //获取拔管时间
                long time2 = drainageTubeRecord.getTubeDrawingTime().getTime();
                if (time1 <= times && time2 >= times) {
                    num1++;
                }
            } else {
                if (time1 <= times) {
                    num1++;
                }
            }

        }
        return num1;
    }

    private int getCrbsiDenominator(Map<String, Object> paramMap) {
        paramMap.put("planFlag", "血管");
        List<DrainageTubeRecord> drainageTubeRecordList = drainageTubeRecordDao.queryAllList(paramMap);
        //获取当前时间
        long time = getTime();
        int num = 0;
        for (int i = 0; i < drainageTubeRecordList.size(); i++) {
            DrainageTubeRecord drainageTubeRecord = drainageTubeRecordList.get(i);
            //获取插管时间
            long time1 = drainageTubeRecord.getIntubationTime().getTime();
            if (drainageTubeRecord.getTubeDrawingTime() != null) {
                //获取拔管时间
                long time2 = drainageTubeRecord.getTubeDrawingTime().getTime();
                if (time1 <= time && time2 >= time) {
                    num++;
                }
            } else {
                if (time1 <= time) {
                    num++;
                }
            }
        }
        return num;
    }

    private long getTime() {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd");//设置当前时间的格式，为年-月-日
        String format = dateFormat.format(date);
        long time = 0l;
        try {
            Date parse = dateFormat.parse(format);
            time = parse.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return time;
    }

    private int getIcuVapDenominator1(Map<String, Object> paramMap) {

        List<IcuLog> icuLogList = icuLogDao.queryIcuVapDenominatorList(paramMap);
        //获取当前时间
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd");//设置当前时间的格式，为年-月-日
        String format = dateFormat.format(date);
        long time = 0l;
        try {
            Date parse = dateFormat.parse(format);
            time = parse.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int num = 0;
        for (int i = 0; i < icuLogList.size(); i++) {
            IcuLog icuLog = icuLogList.get(i);
            //获取发生时间
            long time1 = icuLog.getHappenTime().getTime();
            if (icuLog.getFinishTime() != null) {
                //获取终止时间
                long time2 = icuLog.getFinishTime().getTime();
                if (time1 <= time && time2 >= time) {
                    num++;
                }
            } else {
                if (time1 <= time) {
                    num++;
                }
            }

        }
        return num;
    }

    /**
     * 获取vap质控分母数据
     *
     * @return
     */
    private int getIcuVapDenominator(Map<String, Object> paramMap) {
        List<Patient> patientList = patientDao.queryPatientAll(paramMap);
        if (CollectionUtil.isEmpty(patientList))
            return 0;
        String startTime = (String) paramMap.get("startTime");
        String endTime = (String) paramMap.get("dataTime");
        List<String> dateStringList = sliceUpDateRange(startTime, endTime, 3);
        AtomicInteger haveModeNum = new AtomicInteger();
        patientList.forEach(patient -> {
            String patientId = patient.getId();
            isVitalSignMergeMode(dateStringList, patientId, haveModeNum);
        });
        return haveModeNum.get();
    }

    /**
     * 查询患者再某段时间内是否存在机械通气模式
     *
     * @param dateStringList
     * @param patientId
     * @return
     */
    private void isVitalSignMergeMode(List<String> dateStringList, String patientId, AtomicInteger haveModeNum) {
        if (CollectionUtil.isEmpty(dateStringList))
            return;
        Map<String, Object> map = new HashMap<>();
        map.put("patientId", patientId);
        dateStringList.forEach(dateTime -> {
            map.put("dataTime", dateTime);
            int modeNum = vitalSignMergeDao.queryModeNum(map);
            if (modeNum > 0)
                haveModeNum.addAndGet(1);
        });
    }

    /**
     * 计算占比比率
     *
     * @param molecule    分子
     * @param denominator 分母
     * @return
     */
    private String calculateRate(int molecule, int denominator, String qualitycontrolType) {
        DecimalFormat df = new DecimalFormat("0.00");
        String num;
        if (denominator == 0) {
            num = "0.00";
        } else if (StringUtils.equals(qualitycontrolType, QUALITYCONTROL_TYPE_VAP)) {
            num = df.format(((float) molecule / denominator) * 1000) + "";//返回的是String类型
        } else {
            num = df.format(((float) molecule / denominator) * 100) + "";//返回的是String类型
        }
        return num;
    }

    /**
     * 质控--48h再入科--列表展示统计（按天或者按月）
     *
     * @param map
     * @return
     */
    public List<InOutDepartmentDTO> getFourAndEightList(Map<String, Object> map) {
        LinkedList<InOutDepartmentDTO> list = new LinkedList<>();
        List<String> datetimeList;
        int fourAndEightSumCount = 0;
        int transferPatientCount = 0;
        int fourAndEightRateCount = 0;
        if (map.get("type").toString().equals("按天")) {
            String startTime = map.get("startTime").toString();
            String endTime = map.get("endTime").toString();
            datetimeList = sliceUpDateRange(startTime, endTime, 3);
            //48h返回人数
            //转出患者  判断flag=0  且exit_time =查询时间
            for (String dataTime : datetimeList) {
                InOutDepartmentDTO dto = new InOutDepartmentDTO();
                dto.setDataTime(dataTime);
                System.out.println("dataTime：" + dataTime);
                int fourAndEightSum = getFourAndEightSum(dataTime, "day", startTime);
                // 时间段内转出患者数
                int transferPatientSum = patientDao.getRollOutPatientNum(dataTime, "day", startTime);
                fourAndEightSumCount += fourAndEightSum;
                transferPatientCount += transferPatientSum;
                dto.setFourAndEightSum(fourAndEightSum + "");
                dto.setTransferPatientSum(transferPatientSum + "");
                dto.setFourAndEightRate(calculateRate(fourAndEightSum, transferPatientSum, null));
                System.out.println("总计数据为：" + dto.getFourAndEightRate());
                list.add(dto);
            }
        } else if (map.get("type").toString().equals("按月")) {
            String year = (String) map.get("year");
            datetimeList = sliceUpDateRange(year + "-01", year + "-12", 2);
            for (String dataTime : datetimeList) {
                InOutDepartmentDTO dto = new InOutDepartmentDTO();
                dto.setDataTime(dataTime);
                int fourAndEightSum = getFourAndEightSum(dataTime, "month", year);
                int transferPatientSum = patientDao.getRollOutPatientNum(dataTime, "month", year);
                fourAndEightSumCount += fourAndEightSum;
                transferPatientCount += transferPatientSum;
                dto.setFourAndEightSum(fourAndEightSum + "");
                dto.setTransferPatientSum(transferPatientSum + "");
                dto.setFourAndEightRate(calculateRate(fourAndEightSum, transferPatientSum, null));
                list.add(dto);
            }

        }
        InOutDepartmentDTO sumDto = new InOutDepartmentDTO();
        sumDto.setDataTime("总计");
        sumDto.setFourAndEightSum(fourAndEightSumCount + "");
        sumDto.setTransferPatientSum(transferPatientCount + "");
        sumDto.setFourAndEightRate(calculateRate(fourAndEightSumCount, transferPatientCount, null));
        list.addFirst(sumDto);
        return list;
    }


    /**
     * 质控--48h再入科--折线（按天或者按月）
     *
     * @param map
     * @return
     */
    public Map<String, Object> getFourAndEightNum(Map<String, Object> map) {
        initializeList();
        if (map.get("type").toString().equals("按天")) {
            String startTime = map.get("startTime").toString();
            String endTime = map.get("endTime").toString();
            dateTimeList = sliceUpDateRange(startTime, endTime, 3);
            for (String dataTime : dateTimeList) {
                int fourAndEightSum = getFourAndEightSum(dataTime, "day", startTime);
                int transferPatientSum = patientDao.getRollOutPatientNum(dataTime, "day", startTime);
                moleculeNumList.add(fourAndEightSum);
                denominatorList.add(transferPatientSum);
                rateList.add(calculateRate(fourAndEightSum, transferPatientSum, null));
            }
        } else if (map.get("type").toString().equals("按月")) {
            String year = (String) map.get("year");
            dateTimeList = sliceUpDateRange(year + "-01", year + "-12", 2);
            for (String dataTime : dateTimeList) {
                int fourAndEightSum = getFourAndEightSum(dataTime, "month", year);
                int transferPatientSum = patientDao.getRollOutPatientNum(dataTime, "month", year);
                moleculeNumList.add(fourAndEightSum);
                denominatorList.add(transferPatientSum);
                rateList.add(calculateRate(fourAndEightSum, transferPatientSum, null));
            }
        }
        listMap.put("datetimeList", dateTimeList);
        listMap.put("fourAndEightNumList", moleculeNumList);
        listMap.put("transferPatientNumList", denominatorList);
        listMap.put("fourAndEightRateNumList", rateList);
        return listMap;
    }

    /**
     * 查询48小时内重返患者数
     *
     * @param dataTime
     * @return
     */
    private int getFourAndEightSum(String dataTime, String type, String startTime) {
        AtomicInteger fourAndEightSum = new AtomicInteger();
        fourAndEightSum.set(0);
        //查询某段时间内入科患者
        List<Patient> rollOutPatientList = patientDao.getRollOutPatientList(dataTime, type, startTime);
        rollOutPatientList.forEach(patient -> {
            //查询某个患者是否有入科记录，按入科时间倒叙
            List<Patient> outPatientList = patientDao.queryPatientByVisitIdAndFlag(patient.getVisitId(), "0");
            if (!CollectionUtil.isEmpty(outPatientList)) {
                Patient outPatient = outPatientList.get(0);
                //计算出当前入科时间是大于上次出科时间差值
                if (Objects.nonNull(patient.getEnterTime()) && Objects.nonNull(outPatient.getExitTime())) {
                    long hour = (patient.getEnterTime().getTime() - outPatient.getExitTime().getTime()) / 1000 / 60 / 60;
                    if (hour <= 48) {
                        fourAndEightSum.addAndGet(1);
                    }
                }
            }
        });
        return fourAndEightSum.get();
    }

    /**
     * 质控--APACHEII--列表展示统计（按天或者按月）
     *
     * @param map
     * @return
     */
    public List<ApacheStatisticsReturnDTO> getAPACHEIIList(Map<String, Object> map) {
        LinkedList<ApacheStatisticsReturnDTO> list = new LinkedList<>();
        List<String> datetimeList = new ArrayList<>();
        int fourAndEightSumCount = 0;
        int transferPatientCount = 0;
        int fourAndEightRateCount = 0;
        if (map.get("type").toString().equals("按天")) {
            String startTime = map.get("startTime").toString();
            String endTime = map.get("endTime").toString();
            datetimeList = sliceUpDateRange(startTime, endTime, 3);
            for (String dataTime : datetimeList) {
                /**
                 * 先查询对应日期内，入科人员信息（当天收治多少人，就为同期内收治患者总数），在查询出来对应时间内评分信息，如果相同患者评分信息有多条，则取分数最大的一条
                 * 根据单个患者的入科时间+24小时查询评分信息的集合，如果没有找到，说明属于24小时未评分患者，如果找到了，取分数最大的一条
                 */
                int ge25Number = 0;//大于等25分值患者数
                int between20Or25Number = 0;//20-25之间的患者数
                int between15Or20Number = 0;//15-20之间的患者数
                int between10Or15Number = 0;//10-15之间的患者数
                int le10Number = 0;//小于10的患者数
                int into24NotPassNumber = 0;//24小时未评分患者数
                List<Patient> RollOutPatientList = patientDao.getRollOutPatientList(dataTime, "day", null);//根据对应日期查询当天入科患者信息
                if (!CollectionUtil.isEmpty(RollOutPatientList)) {
                    for (int i = 0; i < RollOutPatientList.size(); i++) {
                        Calendar calendar = new GregorianCalendar();
                        calendar.setTime(RollOutPatientList.get(i).getEnterTime());
                        calendar.add(calendar.DATE, 1);//把日期往后增加一天(24小时)
                        Date date = calendar.getTime();
                        Map conditionMap = new HashMap();
                        conditionMap.put("startTime", RollOutPatientList.get(i).getEnterTime());
                        conditionMap.put("endTime", date);
                        conditionMap.put("scoreType", "apache2");
                        conditionMap.put("visitId", RollOutPatientList.get(i).getVisitId());
                        List<PatientScore> patientScores = patientScoreDao.queryDataListGroup(conditionMap);//查询单个病人自入科24小时内的阿帕奇评分数据
                        if (patientScores.size() != 0) {
                            //对查到的阿帕奇评分数据进行排序，取最大的一个
                            for (int a = 0; a < patientScores.size() - 1; a++) {
                                for (int j = 1; j < patientScores.size() - a; j++) {
                                    PatientScore patientScore;
                                    if (patientScores.get(j - 1).getScore() < (patientScores.get(j).getScore())) { // 比较两个整数的大小
                                        patientScore = patientScores.get(j - 1);
                                        patientScores.set((j - 1), patientScores.get(j));
                                        patientScores.set(j, patientScore);
                                    }
                                }
                            }
                            //遍历判断分数档位，在相关变量+1
                            if (patientScores.get(0).getScore() > 25) {
                                ge25Number++;
                            } else if (patientScores.get(0).getScore() > 20 && patientScores.get(0).getScore() < 25) {
                                between20Or25Number++;
                            } else if (patientScores.get(0).getScore() > 15 && patientScores.get(0).getScore() < 20) {
                                between15Or20Number++;
                            } else if (patientScores.get(0).getScore() > 10 && patientScores.get(0).getScore() < 15) {
                                between10Or15Number++;
                            } else if (patientScores.get(0).getScore() < 10) {
                                le10Number++;
                            }
                        } else {
                            //如果没有查到数据，说明此病人24小时未评分
                            into24NotPassNumber++;
                        }
                    }
                    //计算大于15分患者收治率
                    BigDecimal greater15rate = new BigDecimal(String.valueOf(ge25Number)).add(new BigDecimal(String.valueOf(between20Or25Number)))
                            .add(new BigDecimal(String.valueOf(between15Or20Number))).multiply(new BigDecimal(String.valueOf(100)))
                            .divide(new BigDecimal(String.valueOf(RollOutPatientList.size())), 1, RoundingMode.HALF_UP);

                    //int greater15rate = (ge25Number + between20Or25Number + between15Or20Number) / RollOutPatientList.size() * 100;
                    ApacheStatisticsReturnDTO dto = new ApacheStatisticsReturnDTO();
                    dto.setDateTime(dataTime);
                    dto.setDepartmentsNumber(RollOutPatientList.size());
                    dto.setGe25Number(ge25Number);
                    dto.setBetween20Or25Number(between20Or25Number);
                    dto.setBetween15Or20Number(between15Or20Number);
                    dto.setBetween10Or15Number(between10Or15Number);
                    dto.setLe10Number(le10Number);
                    dto.setInto24NotPassNumber(into24NotPassNumber);
                    dto.setGreater15Number(ge25Number + between20Or25Number + between15Or20Number);
                    dto.setGreater15Rate(greater15rate.toString());
                    list.add(dto);
                } else {
                    ApacheStatisticsReturnDTO dto = new ApacheStatisticsReturnDTO();
                    dto.setDateTime(dataTime);
//                    dto.setDepartmentsNumber(0);
//                    dto.setGe25Number(0);
//                    dto.setBetween20Or25Number(0);
//                    dto.setBetween15Or20Number(0);
//                    dto.setBetween10Or15Number(0);
//                    dto.setLe10Number(0);
//                    dto.setInto24NotPassNumber(0);
//                    dto.setGreater15Number(0);
                    dto.setGreater15Rate("0");
                    list.add(dto);
                }
            }
        } else if (map.get("type").toString().equals("按月")) {
            String year = (String) map.get("year");
            datetimeList = sliceUpDateRange(year + "-01", year + "-12", 2);
            for (String dataTime : datetimeList) {
                /**
                 * 先查询对应日期内，入科人员信息（当天收治多少人，就为同期内收治患者总数），在查询出来对应时间内评分信息，如果相同患者评分信息有多条，则取分数最大的一条
                 * 根据单个患者的入科时间+24小时查询评分信息的集合，如果没有找到，说明属于24小时未评分患者，如果找到了，取分数最大的一条
                 */
                int ge25Number = 0;//大于等25分值患者数
                int between20Or25Number = 0;//20-25之间的患者数
                int between15Or20Number = 0;//15-20之间的患者数
                int between10Or15Number = 0;//10-15之间的患者数
                int le10Number = 0;//小于10的患者数
                int into24NotPassNumber = 0;//24小时未评分患者数
                List<Patient> RollOutPatientList = patientDao.getRollOutPatientList(dataTime, "month", null);//根据对应日期查询当天入科患者信息
                if (!CollectionUtil.isEmpty(RollOutPatientList)) {
                    for (int i = 0; i < RollOutPatientList.size(); i++) {
                        Calendar calendar = new GregorianCalendar();
                        calendar.setTime(RollOutPatientList.get(i).getEnterTime());
                        calendar.add(calendar.DATE, 1);//把日期往后增加一天(24小时)
                        Date date = calendar.getTime();
                        Map conditionMap = new HashMap();
                        conditionMap.put("startTime", RollOutPatientList.get(i).getEnterTime());
                        conditionMap.put("endTime", date);
                        conditionMap.put("scoreType", "apache2");
                        conditionMap.put("visitId", RollOutPatientList.get(i).getVisitId());
                        List<PatientScore> patientScores = patientScoreDao.queryDataListGroup(conditionMap);//查询单个病人自入科24小时内的阿帕奇评分数据
                        if (patientScores.size() != 0) {
                            //对查到的阿帕奇评分数据进行排序，取最大的一个
                            for (int a = 0; a < patientScores.size() - 1; a++) {
                                for (int j = 1; j < patientScores.size() - a; j++) {
                                    PatientScore patientScore;
                                    if (patientScores.get(j - 1).getScore() < (patientScores.get(j).getScore())) { // 比较两个整数的大小
                                        patientScore = patientScores.get(j - 1);
                                        patientScores.set((j - 1), patientScores.get(j));
                                        patientScores.set(j, patientScore);
                                    }
                                }
                            }
                            //遍历判断分数档位，在相关变量+1
                            if (patientScores.get(0).getScore() > 25) {
                                ge25Number++;
                            } else if (patientScores.get(0).getScore() > 20 && patientScores.get(0).getScore() < 25) {
                                between20Or25Number++;
                            } else if (patientScores.get(0).getScore() > 15 && patientScores.get(0).getScore() < 20) {
                                between15Or20Number++;
                            } else if (patientScores.get(0).getScore() > 10 && patientScores.get(0).getScore() < 15) {
                                between10Or15Number++;
                            } else if (patientScores.get(0).getScore() < 10) {
                                le10Number++;
                            }

                        } else {
                            //如果没有查到数据，说明此病人24小时未评分
                            into24NotPassNumber++;
                        }
                    }
                    //计算大于15分患者收治率
                    BigDecimal greater15rate = new BigDecimal(String.valueOf(ge25Number)).add(new BigDecimal(String.valueOf(between20Or25Number)))
                            .add(new BigDecimal(String.valueOf(between15Or20Number))).multiply(new BigDecimal(String.valueOf(100)))
                            .divide(new BigDecimal(String.valueOf(RollOutPatientList.size())), 1, RoundingMode.HALF_UP);
                    //int greater15rate = (ge25Number + between20Or25Number + between15Or20Number) / RollOutPatientList.size() * 100;
                    ApacheStatisticsReturnDTO dto = new ApacheStatisticsReturnDTO();
                    dto.setDateTime(dataTime);
                    dto.setDepartmentsNumber(RollOutPatientList.size());
                    dto.setGe25Number(ge25Number);
                    dto.setBetween20Or25Number(between20Or25Number);
                    dto.setBetween15Or20Number(between15Or20Number);
                    dto.setBetween10Or15Number(between10Or15Number);
                    dto.setLe10Number(le10Number);
                    dto.setInto24NotPassNumber(into24NotPassNumber);
                    dto.setGreater15Number(ge25Number + between20Or25Number + between15Or20Number);
                    dto.setGreater15Rate(greater15rate.toString());
                    list.add(dto);
                } else {
                    ApacheStatisticsReturnDTO dto = new ApacheStatisticsReturnDTO();
                    dto.setDateTime(dataTime);
//                    dto.setDepartmentsNumber(0);
//                    dto.setGe25Number(0);
//                    dto.setBetween20Or25Number(0);
//                    dto.setBetween15Or20Number(0);
//                    dto.setBetween10Or15Number(0);
//                    dto.setLe10Number(0);
//                    dto.setInto24NotPassNumber(0);
//                    dto.setGreater15Number(0);
                    dto.setGreater15Rate("0");
                    list.add(dto);
                }
            }
        }
        int Departments = 0;
        int Ge25 = 0;
        int Between20Or25 = 0;
        int Between15Or20 = 0;
        int Between10Or15 = 0;
        int Le10 = 0;
        int Into24NotPass = 0;
        int Greater15 = 0;
        for (int i = 0; i < list.size(); i++) {
            Departments = Departments + Integer.valueOf(list.get(i).getDepartmentsNumber());
            Ge25 = Ge25 + Integer.valueOf(list.get(i).getGe25Number());
            Between20Or25 = Between20Or25 + Integer.valueOf(list.get(i).getBetween20Or25Number());
            Between15Or20 = Between15Or20 + Integer.valueOf(list.get(i).getBetween15Or20Number());
            Between10Or15 = Between10Or15 + Integer.valueOf(list.get(i).getBetween10Or15Number());
            Le10 = Le10 + Integer.valueOf(list.get(i).getLe10Number());
            Into24NotPass = Into24NotPass + Integer.valueOf(list.get(i).getInto24NotPassNumber());
            Greater15 = Greater15 + Integer.valueOf(list.get(i).getGreater15Number());
        }
        ApacheStatisticsReturnDTO sumdto = new ApacheStatisticsReturnDTO();
        sumdto.setDateTime("总计");
        sumdto.setDepartmentsNumber(Departments);
        sumdto.setGe25Number(Ge25);
        sumdto.setBetween20Or25Number(Between20Or25);
        sumdto.setBetween15Or20Number(Between15Or20);
        sumdto.setBetween10Or15Number(Between10Or15);
        sumdto.setLe10Number(Le10);
        sumdto.setInto24NotPassNumber(Into24NotPass);
        sumdto.setGreater15Rate("-");
        sumdto.setGreater15Number(Greater15);
        list.addFirst(sumdto);
        return list;
    }

    /**
     * 质控--APACHEII--折线（按天或者按月）
     *
     * @param map
     * @return
     */
    public Map<String, Object> getAPACHEIINum(Map<String, Object> map) {
        Map<String, Object> listMap = new HashMap<String, Object>();
        List<String> datetimeList = new ArrayList<String>();//时间
        List<Integer> departmentsNumberList = new ArrayList<Integer>();//科室收治数
        List<Integer> ge25NumberList = new ArrayList<Integer>();//大于等25分值患者数
        List<Integer> between20Or25NumberList = new ArrayList<Integer>();//20-25之间的患者数
        List<Integer> between15Or20NumberList = new ArrayList<Integer>();//15-20之间的患者数
        List<Integer> between10Or15NumberList = new ArrayList<Integer>();//10-15之间的患者数
        List<Integer> le10NumberList = new ArrayList<Integer>();//小于10的患者数
        List<Integer> into24NotPassNumberList = new ArrayList<Integer>();//入科24小时未评分患者数
        List<String> greater15RateList = new ArrayList<String>();//大于15分患者收治率
        List<Integer> greater15NumberList = new ArrayList<Integer>();//大于15分患者收治数
        DecimalFormat df = new DecimalFormat("0.00");

        if (map.get("type").toString().equals("按天")) {
            String startTime = map.get("startTime").toString();
            String endTime = map.get("endTime").toString();
            datetimeList = sliceUpDateRange(startTime, endTime, 3);
            for (String dataTime : datetimeList) {
                /**
                 * 先查询对应日期内，入科人员信息（当天收治多少人，就为同期内收治患者总数），再查询出来对应时间内评分信息，如果相同患者评分信息有多条，则取分数最大的一条
                 * 根据单个患者的入科时间+24小时查询评分信息的集合，如果没有找到，说明属于24小时未评分患者，如果找到了，取分数最大的一条
                 */
                int ge25Number = 0;//大于等25分值患者数
                int between20Or25Number = 0;//20-25之间的患者数
                int between15Or20Number = 0;//15-20之间的患者数
                int between10Or15Number = 0;//10-15之间的患者数
                int le10Number = 0;//小于10的患者数
                int into24NotPassNumber = 0;//24小时未评分患者数
                List<Patient> RollOutPatientList = patientDao.getRollOutPatientList(dataTime, "day", null);//根据对应日期查询当天入科患者信息
                if (!CollectionUtil.isEmpty(RollOutPatientList)) {
                    for (int i = 0; i < RollOutPatientList.size(); i++) {
                        Calendar calendar = new GregorianCalendar();
                        calendar.setTime(RollOutPatientList.get(i).getEnterTime());
                        calendar.add(calendar.DATE, 1);//把日期往后增加一天(24小时)
                        Date date = calendar.getTime();

                        Map conditionMap = new HashMap();
                        conditionMap.put("startTime", RollOutPatientList.get(i).getEnterTime());
                        conditionMap.put("endTime", date);
                        conditionMap.put("scoreType", "apache2");
                        conditionMap.put("visitId", RollOutPatientList.get(i).getVisitId());
                        List<PatientScore> patientScores = patientScoreDao.queryDataListGroup(conditionMap);//查询单个病人自入科24小时内的阿帕奇评分数据
                        if (patientScores.size() != 0) {
                            //对查到的阿帕奇评分数据进行排序，取最大的一个
                            for (int a = 0; a < patientScores.size() - 1; a++) {
                                for (int j = 1; j < patientScores.size() - a; j++) {
                                    PatientScore patientScore;
                                    if (patientScores.get(j - 1).getScore() < (patientScores.get(j).getScore())) { // 比较两个整数的大小
                                        patientScore = patientScores.get(j - 1);
                                        patientScores.set((j - 1), patientScores.get(j));
                                        patientScores.set(j, patientScore);
                                    }
                                }
                            }
                            //遍历判断分数档位，在相关变量+1
                            if (patientScores.get(0).getScore() > 25) {
                                ge25Number++;
                            } else if (patientScores.get(0).getScore() > 20 && patientScores.get(0).getScore() < 25) {
                                between20Or25Number++;
                            } else if (patientScores.get(0).getScore() > 15 && patientScores.get(0).getScore() < 20) {
                                between15Or20Number++;
                            } else if (patientScores.get(0).getScore() > 10 && patientScores.get(0).getScore() < 15) {
                                between10Or15Number++;
                            } else if (patientScores.get(0).getScore() < 10) {
                                le10Number++;
                            }

                        } else {
                            //如果没有查到数据，说明此病人24小时未评分
                            into24NotPassNumber++;
                        }
                    }
                    //计算大于15分患者收治率
                    BigDecimal greater15rate = new BigDecimal(String.valueOf(ge25Number)).add(new BigDecimal(String.valueOf(between20Or25Number)))
                            .add(new BigDecimal(String.valueOf(between15Or20Number))).multiply(new BigDecimal(String.valueOf(100)))
                            .divide(new BigDecimal(String.valueOf(RollOutPatientList.size())), 1, RoundingMode.HALF_UP);
                    //int greater15rate = (ge25Number + between20Or25Number + between15Or20Number) / RollOutPatientList.size() * 100;

                    departmentsNumberList.add(RollOutPatientList.size());//患者总数
                    ge25NumberList.add(ge25Number);//大于等25分值患者数
                    between20Or25NumberList.add(between20Or25Number);//20-25之间的患者数
                    between15Or20NumberList.add(between15Or20Number);//15-20之间的患者数
                    between10Or15NumberList.add(between10Or15Number);//10-15之间的患者数
                    le10NumberList.add(le10Number);//小于10的患者数
                    into24NotPassNumberList.add(into24NotPassNumber);//入科24小时未评分患者数
                    greater15NumberList.add(ge25Number + between20Or25Number + between15Or20Number);//大于15分患者收治数
                    greater15RateList.add(greater15rate.toString());//大于15分患者收治率

                } else {
                    departmentsNumberList.add(0);//患者总数
                    ge25NumberList.add(0);//大于等25分值患者数
                    between20Or25NumberList.add(0);//20-25之间的患者数
                    between15Or20NumberList.add(0);//15-20之间的患者数
                    between10Or15NumberList.add(0);//10-15之间的患者数
                    le10NumberList.add(0);//小于10的患者数
                    into24NotPassNumberList.add(0);//入科24小时未评分患者数
                    greater15NumberList.add(0);//大于15分患者收治率
                    greater15RateList.add("0");//大于15分患者收治率
                }
            }
        } else if (map.get("type").toString().equals("按月")) {
            String year = (String) map.get("year");
            datetimeList = sliceUpDateRange(year + "-01", year + "-12", 2);
            for (String dataTime : datetimeList) {

                int ge25Number = 0;//大于等25分值患者数
                int between20Or25Number = 0;//20-25之间的患者数
                int between15Or20Number = 0;//15-20之间的患者数
                int between10Or15Number = 0;//10-15之间的患者数
                int le10Number = 0;//小于10的患者数
                int into24NotPassNumber = 0;//24小时未评分患者数
                List<Patient> RollOutPatientList = patientDao.getRollOutPatientList(dataTime, "month", null);//根据对应日期查询当天入科患者信息
                if (!CollectionUtil.isEmpty(RollOutPatientList)) {
                    for (int i = 0; i < RollOutPatientList.size(); i++) {
                        Calendar calendar = new GregorianCalendar();
                        calendar.setTime(RollOutPatientList.get(i).getEnterTime());
                        calendar.add(calendar.DATE, 1);//把日期往后增加一天(24小时)
                        Date date = calendar.getTime();

                        Map conditionMap = new HashMap();
                        conditionMap.put("startTime", RollOutPatientList.get(i).getEnterTime());
                        conditionMap.put("endTime", date);
                        conditionMap.put("scoreType", "apache2");
                        conditionMap.put("visitId", RollOutPatientList.get(i).getVisitId());
                        List<PatientScore> patientScores = patientScoreDao.queryDataListGroup(conditionMap);//查询单个病人自入科24小时内的阿帕奇评分数据
                        if (patientScores.size() != 0) {
                            //对查到的阿帕奇评分数据进行排序，取最大的一个
                            for (int a = 0; a < patientScores.size() - 1; a++) {
                                for (int j = 1; j < patientScores.size() - a; j++) {
                                    PatientScore patientScore;
                                    if (patientScores.get(j - 1).getScore() < (patientScores.get(j).getScore())) { // 比较两个整数的大小
                                        patientScore = patientScores.get(j - 1);
                                        patientScores.set((j - 1), patientScores.get(j));
                                        patientScores.set(j, patientScore);
                                    }
                                }
                            }
                            //遍历判断分数档位，在相关变量+1
                            if (patientScores.get(0).getScore() > 25) {
                                ge25Number++;
                            } else if (patientScores.get(0).getScore() > 20 && patientScores.get(0).getScore() < 25) {
                                between20Or25Number++;
                            } else if (patientScores.get(0).getScore() > 15 && patientScores.get(0).getScore() < 20) {
                                between15Or20Number++;
                            } else if (patientScores.get(0).getScore() > 10 && patientScores.get(0).getScore() < 15) {
                                between10Or15Number++;
                            } else if (patientScores.get(0).getScore() < 10) {
                                le10Number++;
                            }

                        } else {
                            //如果没有查到数据，说明此病人24小时未评分
                            into24NotPassNumber++;
                        }
                    }
                    //计算大于15分患者收治率
                    BigDecimal greater15rate = new BigDecimal(String.valueOf(ge25Number)).add(new BigDecimal(String.valueOf(between20Or25Number)))
                            .add(new BigDecimal(String.valueOf(between15Or20Number))).multiply(new BigDecimal(String.valueOf(100)))
                            .divide(new BigDecimal(String.valueOf(RollOutPatientList.size())), 1, RoundingMode.HALF_UP);
                    //int greater15rate = (ge25Number + between20Or25Number + between15Or20Number) / RollOutPatientList.size() * 100;

                    departmentsNumberList.add(RollOutPatientList.size());//患者总数
                    ge25NumberList.add(ge25Number);//大于等25分值患者数
                    between20Or25NumberList.add(between20Or25Number);//20-25之间的患者数
                    between15Or20NumberList.add(between15Or20Number);//15-20之间的患者数
                    between10Or15NumberList.add(between10Or15Number);//10-15之间的患者数
                    le10NumberList.add(le10Number);//小于10的患者数
                    into24NotPassNumberList.add(into24NotPassNumber);//入科24小时未评分患者数
                    greater15NumberList.add(ge25Number + between20Or25Number + between15Or20Number);//大于15分患者收治率
                    greater15RateList.add(greater15rate.toString());//大于15分患者收治率

                } else {
                    departmentsNumberList.add(0);//患者总数
                    ge25NumberList.add(0);//大于等25分值患者数
                    between20Or25NumberList.add(0);//20-25之间的患者数
                    between15Or20NumberList.add(0);//15-20之间的患者数
                    between10Or15NumberList.add(0);//10-15之间的患者数
                    le10NumberList.add(0);//小于10的患者数
                    into24NotPassNumberList.add(0);//入科24小时未评分患者数
                    greater15NumberList.add(0);//大于15分患者收治率
                    greater15RateList.add("0");//大于15分患者收治率
                }


            }

        }
        listMap.put("datetimeList", datetimeList);
        listMap.put("departmentsNumberList", departmentsNumberList);
//        listMap.put("ge25NumberList", ge25NumberList);
//        listMap.put("between20Or25NumberList", between20Or25NumberList);
//        listMap.put("between15Or20NumberList", between15Or20NumberList);
//        listMap.put("between10Or15NumberList", between10Or15NumberList);
//        listMap.put("le10NumberList", le10NumberList);
//        listMap.put("into24NotPassNumberList", into24NotPassNumberList);
        listMap.put("greater15NumberList", greater15NumberList);
        listMap.put("greater15RateList", greater15RateList);
        return listMap;
    }

    /**
     * 3hBundle
     * 列表
     *
     * @param map
     * @return
     */
    public HttpResult get3hBundleNumList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_3hBundle), "数据请求成功");
    }

    /**
     * 折线
     *
     * @param map
     * @return
     */
    public HttpResult get3hBundleBroken(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_3hBundle);
    }

    /**
     * 导出
     *
     * @param map
     * @param response
     * @return
     */
    public HttpResult download3hBundleTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_3hBundle, "进行感染性休克3h集束化治疗（bundle）完成信息统计表", "入icu诊断为感染性休克并全部完成3hbundle的患者数",
                "同期入icu诊断为感染休克患者总数", "感染性休克3h集束化治疗（bundle）完成率（%）");
    }

    /**
     * 6hBundle
     *
     * @param map
     * @return
     */
    public HttpResult get6hBundleNumList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_6hBundle), "数据请求成功");
    }

    public HttpResult get6hBundleBrokenList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_6hBundle);
    }

    public HttpResult download6hBundleTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_6hBundle, "进行感染性休克6h集束化治疗（bundle）完成信息统计表", "入icu诊断为感染性休克并全部完成6hbundle的患者数",
                "同期入icu诊断为感染休克患者总数", "感染性休克6h集束化治疗（bundle）完成率（%）");
    }

    /**
     * DVT
     *
     * @param map
     * @return
     */
    public HttpResult getDvtList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_DVT), "数据请求成功");
    }

    public HttpResult getDvtBrokenList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_DVT);
    }

    public HttpResult downloadDvtTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_DVT, "进行ICU深静脉血栓（DVT）预防信息统计表", "进行深静脉血栓（DVT）预防的ICU患者数",
                "同期ICU收治患者总数的比例", "ICU深静脉血栓（DVT）（%）");
    }

    /**
     * VAP
     *
     * @param map
     * @return
     */
    public HttpResult getVapList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_VAP), "数据请求成功");
    }

    public HttpResult getVapBrokenList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_VAP);
    }

    public HttpResult downloadVapTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_VAP, "进行呼吸机相关性肺炎（VAP）的预防信息统计表", "VAP发生例数",
                "同期ICU患者有创机械通气总天数", "ICU呼吸机相关性肺炎（VAP）发病率（‰）");
    }

    /**
     * icu收治率
     *
     * @param map
     * @return
     */
    public HttpResult getPatientGiveList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_PATIENT_GIVE), "数据请求成功");
    }

    public HttpResult getPatientGiveBrokenList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_PATIENT_GIVE);
    }

    public HttpResult downloadPatientGiveTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_PATIENT_GIVE, "ICU患者收治率信息统计表",
                "ICU收治患者总数", "同期医院收治患者总数", "ICU患者收治率（%）");
    }

    /**
     * 床日率
     *
     * @param map
     * @return
     */
    public HttpResult getBedToDayList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_BEDTODAY), "数据请求成功");
    }

    public HttpResult getBedToDayBrokenList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_BEDTODAY);
    }

    public HttpResult downloadBedToDayTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_BEDTODAY, "ICU患者收治床日率信息统计表",
                "ICU收治患者总床日数", "同期医院收治患者总床日数", "ICU患者收治床日率（%）");
    }

    /**
     * 插拔管48小时率
     *
     * @param map
     * @return
     */
    public HttpResult getPipeline48hList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_PIPELINE48H), "数据请求成功");
    }

    public HttpResult getPipeline48hBrokenList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_PIPELINE48H);
    }

    public HttpResult downloadPipeline48hTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_PIPELINE48H, "气管插管拔管后48h内再插管率信息统计表",
                "气管插管计划拔管后48h内再插管例数", "同期ICU患者气管插管拔管总例数", "气管插管拔管后48h内再插管率（%）");
    }

    /**
     * 细菌感染
     *
     * @param map
     * @return
     */

    public HttpResult getBacillosisList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_BACILLOSOS), "数据请求成功");
    }

    public HttpResult getBacillosisBrokenList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_BACILLOSOS);
    }

    public HttpResult downloadBacillosisTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_BACILLOSOS, "ICU抗菌药物治疗前病原学送检率信息统计表",
                "使用抗菌药物前病原学检验标本送检病例数", "同期使用抗菌药物治疗病例总数", "ICU抗菌药物治疗前病原学送检率（%）");
    }

    /**
     * Crbsi
     *
     * @param map
     * @return
     */
    public HttpResult getCrbsiList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_CRBSI), "数据请求成功");
    }

    public HttpResult getCrbsiBrokenList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_CRBSI);
    }

    public HttpResult downloadCrbsiTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_CRBSI, "ICU血管内导管相关血流感染（CRBSI）发病率信息统计表",
                "CRBSI发生例数", "同期ICU患者血管内导管留置总天数", "ICU血管内导管相关血流感染（CRBSI）发病率（‰）");
    }

    /**
     * Cauti
     *
     * @param map
     * @return
     */
    public HttpResult getCautiList(Map<String, Object> map) {
        errorIfEmpty(map, "查询参数数据不能为空");
        return new HttpResult(200, getInOutDepartmentList(map, QUALITYCONTROL_TYPE_CAUTI), "数据请求成功");
    }

    public HttpResult getCautiBrokenList(Map<String, Object> map) {
        return getQualitycontrolList(map, QUALITYCONTROL_TYPE_CAUTI);
    }

    public HttpResult downloadCautiTotal(Map<String, Object> map, HttpServletResponse response) {
        return getDownloadTotal(map, response, QUALITYCONTROL_TYPE_CAUTI, "CAUTI发生例数",
                "同期ICU患者导尿管留置总天数", "ICU导尿管相关泌尿系感染（CAUTI）发病率信息统计表", "ICU导尿管相关泌尿系感染（CAUTI）发病率（‰）");
    }
}
